import 'dart:async';

import 'package:baseProjectFlutter/utils/result_extend.dart';

import '../timer_extends.dart';

///Completer 扩展方法
extension CompleterExtends<T> on Completer<T> {
  void cancel() {
    try {
      if (!isCompleted) {
        completeError(CancelException('Task cancelled'));
      }
    } catch (e) {}
  }
}

class CancelException implements Exception {
  final String message;

  CancelException(this.message);

  String toString() => "CancelException: $message";
}

/// CancellationToken 用于管理取消操作
class CancellationToken {
  bool _isCancelled = false;

  bool get isCancelled => _isCancelled;

  void cancel() {
    _isCancelled = true;
  }
}

class TimerCompleter {
  Timer? timer;
  Completer completer;

  TimerCompleter(this.timer, this.completer);

  void cancel() {
    timer?.cancel();
    completer.cancel();
  }
}

/// Future 扩展方法
extension FutureExtends<T> on Future<T> {
  Future<T> withCancel(CancellationToken cancellationToken) {
    return then((value) {
      if (cancellationToken.isCancelled) {
        throw CancelException("Task cancelled");
      }
      return value;
    }).catchError((error) {
      if (cancellationToken.isCancelled) {
        // throw CancelException("Task cancelled");
      }
      throw error;
    });
  }
}

class Job {
  final Completer _completer;
  final CancellationToken _cancellationToken = CancellationToken();

  Job([Completer? completer]) : _completer = completer ?? Completer();

  get isCancel => _cancellationToken.isCancelled;

  get isActive => !isCancel && !isCompleted;

  Completer get completer => _completer;

  Future get future => _completer.future;

  bool get isCompleted => _completer.isCompleted;

  void cancel() {
    if (!isCompleted) {
      _cancellationToken.cancel();
      _completer.cancel();
    }
  }

  /// 任意 await 语句前检查取消标记
  Future<T> withCancel<T>(Future<T> future) async {
    return await future.withCancel(_cancellationToken);
  }

  //只有使用这个方法延迟才能被取消后续代码执行
  Future<void> delay(int delay) {
    return withCancel(delayFuture(delay));
  }

  Future catchError(Function onError, {bool Function(Object error)? test}) {
    future.catchError(onError);
    return future;
  }
}

//作用域
class CoroutineScope {
  final Set<Job> _tasks = {};
  final CancellationToken _cancellationToken = CancellationToken();

  Job launch(Future Function(CoroutineScope, Job) task, [Function? onError]) {
    final job = Job(Completer());
    _tasks.add(job);

    Future wrappedTask() async {
      try {
        await task(this, job);
        job.completer.complete();
      } catch (e, s) {
        if (!job.isCompleted) {
          job.completer.completeError(e, s);
        }
      } finally {
        _tasks.remove(job);
      }
    }

    wrappedTask();
    //这里需要捕获异常，否则会抛出异常
    job.future.catchError((e, s) {
      if (onError != null) {
        if (onError is dynamic Function(Object, StackTrace)) {
          onError(e, s);
        } else if (onError is dynamic Function(Object)) {
          onError(e);
        } else {
          onError();
        }
      }
    });
    return job;
  }

  void cancel() {
    for (final job in _tasks) {
      if (!job.isCompleted) {
        job.cancel();
      }
    }
    _cancellationToken.cancel();
    _tasks.clear();
  }

  /// 任意 await 语句前检查取消标记
  Future<T> withCancel<T>(Future<T> future) async {
    return await future.withCancel(_cancellationToken);
  }

  //只有使用这个方法延迟才能被取消后续代码执行
  Future<void> delay(int delay) {
    return withCancel(delayFuture(delay));
  }
}

///启动一个异步任务，并返回一个Completer对象，用于取消任务。
Job launch<T>(Future<T> Function(CoroutineScope) task, [Function? onError]) {
  return CoroutineScope().launch((scope, job) async {
    try {
      await task(scope);
    } catch (e, s) {
      if (onError != null) {
        if (onError is dynamic Function(Object, StackTrace)) {
          onError(e, s);
        } else if (onError is dynamic Function(Object)) {
          onError(e);
        } else {
          onError();
        }
      }
    }
  });
}

///启动一个异步任务，并返回一个Completer对象，用于取消任务。
Job launchSJ<T>(Future<T> Function(CoroutineScope, Job) task, [Function? onError]) {
  return CoroutineScope().launch((scope, job) async {
    try {
      await task(scope, job);
    } catch (e, s) {
      if (onError != null) {
        if (onError is dynamic Function(Object, StackTrace)) {
          onError(e, s);
        } else if (onError is dynamic Function(Object)) {
          onError(e);
        } else {
          onError();
        }
      }
    }
  });
}

///启动一个异步任务，并返回一个Completer对象，用于取消任务。
Job launchJob<T>(Future<T> Function(Job) task, [Function? onError]) {
  return CoroutineScope().launch((scope, job) async {
    try {
      await task(job);
    } catch (e, s) {
      if (onError != null) {
        if (onError is dynamic Function(Object, StackTrace)) {
          onError(e, s);
        } else if (onError is dynamic Function(Object)) {
          onError(e);
        } else {
          onError();
        }
      }
    }
  });
}

void main() async {
  print(DateTime.now().millisecond);
  print(DateTime.now().millisecondsSinceEpoch);
  Future aaa(Job job) async {
    await delayFuture(4000);
  }

  final task = launchSJ((scope, job) async {
    while (job.isActive) {
      print("111111111111 run");
      // await job.withCancel(delayFuture(4000));
      await job.withCancel(aaa(job));
      print("111111111111");
    }
  });

  taskLaunch(() async {
    print("222222222 run");
    await delayFuture(2000);
    print("222222222");
    task.cancel();
  });
  taskLaunch(() async {
    print("3333333333 run");
    await delayFuture(6000);
    print("3333333333");
  });
  print('End');
}
